package manipulador;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import agenda.Contato;

/*
 * Element: representa um elemento XML
 * Attr: representa um atributo do elemento XML
 * Text: é o conteúdo de um elemento. 
 * Document: representa o documento XML. Apenas um objeto Document existe em cada XML que você fazer o parse. 
 * 
 */

public class XMLComDOM {

	private DocumentBuilderFactory dbf;
	private DocumentBuilder db;
	private Document doc;
	
	/**
	 * Instancia o DocumentBuilderFactory
	 * @throws SAXException
	 * @throws IOException
	 */
	public XMLComDOM(){
		dbf = DocumentBuilderFactory.newInstance();
		try {
			db = dbf.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			System.out.println("DocumentBuilder não pode ser criado.");
			e.printStackTrace();
		}
	}
	
	/**
	 * Realiza a leitura do arquivo XML passado como parametro
	 * @param arquivoXML path/nome do arquivo XML
	 * @return lista de contatos contidos no arquivo XML
	 * @throws SAXException
	 * @throws IOException
	 */
	public List<Contato> readerXML(String arquivoXML) throws SAXException, IOException{
		this.doc = this.db.parse(arquivoXML);
		Element raiz = doc.getDocumentElement();
		System.out.println("O elemento raiz é: " + raiz.getNodeName());
		NodeList listaContatos = raiz.getElementsByTagName("contato");
		List<Contato> lista = new ArrayList<Contato>(listaContatos.getLength());
		for (int i=0; i<listaContatos.getLength(); i++){
			Element elementoContato = (Element) listaContatos.item(i);
			Contato contato = criaContato(elementoContato);
			lista.add(contato);
		}
		return lista;		
	}
	
	/**
	 * Cria um objeto Contato a partir das informações do arquivo XML
	 * @param elemento que se deseja extrair o conteúdo
	 * @return Contato
	 */
	public Contato criaContato(Element elemento){
		Contato contato = new Contato();
		contato.setId(Integer.parseInt(elemento.getAttributeNode("id").getNodeValue()));
		contato.setNome(obterValorElemento(elemento,"nome"));
		contato.setEndereco(obterValorElemento(elemento,"endereco"));
		contato.setTelefone(obterValorElemento(elemento,"telefone"));
		contato.setEmail(obterValorElemento(elemento,"email"));
		return contato;
	}
	
	/**
	 * Obtém o valor do Text Node de um determinado elemento (se este possuir valor)
	 * @param elemento objeto que deseja-se obter o valor
	 * @param nomeElemento nome da tag cujo valor deseja-se obter
	 * @return valor da tag/elemento se esta existir ou null caso não exista
	 */
	public String obterValorElemento(Element elemento, String nomeElemento){
		NodeList listaElemento = elemento.getElementsByTagName(nomeElemento);
		for(int i=0; i<listaElemento.getLength(); i++){
			Element noElemento = (Element) listaElemento.item(i);
			Node no = noElemento.getFirstChild();
		}
		if (listaElemento == null){
			return null;
		}
		Element noElemento = (Element) listaElemento.item(0);
		if (noElemento == null){
			return null;
		}
		Node no = noElemento.getFirstChild();
		return no.getNodeValue();
	}
	

	public static void main(String[] args) {
		// Parser é código que faz a leitura de um documento XML e analisa a sua estrutura.
		XMLComDOM parser = new XMLComDOM();
		try {
			List<Contato> contatos = parser.readerXML("agenda.xml");
			for (Contato contato : contatos){
				System.out.println(contato);
			}
		} catch (SAXException e) {
			System.out.println("Problema ao fazer o parse do arquivo.");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("Erro ao ler o arquivo.");
			e.printStackTrace();
		}

	}

}
